package com.cloud.lan.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cloud.lan.api.dto.resp.LanUserResp;
import com.cloud.lan.config.cache.LoadingCacheConfiguration;
import com.cloud.lan.dao.LanBookingActivityMapper;
import com.cloud.lan.dao.LanBookingActivityRecordMapper;
import com.cloud.lan.entity.base.BaseResponse;
import com.cloud.lan.entity.model.dataobject.LanBookingActivityDO;
import com.cloud.lan.entity.model.dataobject.LanBookingActivityRecordDO;
import com.cloud.lan.service.ILanBookingActivityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Created by zhouquan on 2022/5/1.
 */
@Slf4j
@Service
public class LanBookingActivityServiceImpl  implements ILanBookingActivityService {

    @Resource
    private LoadingCacheConfiguration cacheConfiguration;
    @Resource
    private LanBookingActivityMapper lanBookingActivityMapper;
    @Resource
    private LanBookingActivityRecordMapper lanBookingActivityRecordMapper;

    private static final String LANCASTER_APP_CODE="LANCASTER";

    @Override
    public BaseResponse<Object> queryLatestValidAC(String token, String appCode) {
        LambdaQueryWrapper<LanBookingActivityDO> larQw = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(appCode)){
            larQw.eq(LanBookingActivityDO::getAppCode,appCode);
        }else{
            larQw.eq(LanBookingActivityDO::getAppCode,LANCASTER_APP_CODE);
        }
        larQw.eq(LanBookingActivityDO::getStatus,1);
        Date nowD = new Date();
        larQw.lt(LanBookingActivityDO::getStartTime,nowD);
        larQw.gt(LanBookingActivityDO::getEndTime,nowD);
        larQw.eq(LanBookingActivityDO::getIsDeleted,0);
        larQw.orderByDesc(LanBookingActivityDO::getId);
        LanBookingActivityDO activityDO = lanBookingActivityMapper.selectOne(larQw);
        //判断活动参与人数是否到达阈值
        if(Objects.nonNull(activityDO)){
            LambdaQueryWrapper<LanBookingActivityRecordDO> larQwRecord = new LambdaQueryWrapper<>();
            larQwRecord.eq(LanBookingActivityRecordDO::getActivityId,activityDO.getId());
            larQwRecord.eq(LanBookingActivityRecordDO::getIsDeleted,0);
            int totalRecords = lanBookingActivityRecordMapper.selectCount(larQwRecord);
            if(totalRecords>=activityDO.getAcCount()){
                log.info("该活动目前参与人数已达活动上限:[{}]", JSON.toJSONString(activityDO));
                return BaseResponse.success();
            }
        }
        return BaseResponse.success(activityDO);
    }

    @Override
    public BaseResponse<Object> queryUserLatestACR(String token,Long activityId) {
        LanUserResp lanUserResp = cacheConfiguration.userInfo.getUnchecked(token);
        if(Objects.isNull(lanUserResp)){
            return BaseResponse.error(BaseResponse.ERROR_TOKEN_NO,"token无效");
        }
        LambdaQueryWrapper<LanBookingActivityRecordDO> larQw = new LambdaQueryWrapper<>();
        larQw.eq(LanBookingActivityRecordDO::getActivityId,activityId);
        larQw.eq(LanBookingActivityRecordDO::getUserId,lanUserResp.getUserId());
        larQw.eq(LanBookingActivityRecordDO::getIsDeleted,0);
        larQw.orderByDesc(LanBookingActivityRecordDO::getId);
        LanBookingActivityRecordDO recordDO = lanBookingActivityRecordMapper.selectOne(larQw);
        return BaseResponse.success(recordDO);
    }

    @Override
    public BaseResponse applyJoin (String token, LanBookingActivityRecordDO reqDo) {
        BaseResponse exitRes = queryUserLatestACR(token,reqDo.getActivityId());
        if(Objects.nonNull(exitRes.getData())){
            return BaseResponse.error(BaseResponse.ERROR,"已参加过活动");
        }
        String failReason = checkAcIsValid(reqDo.getActivityId());
        if(StringUtils.isNotBlank(failReason)){
            return BaseResponse.error(BaseResponse.ERROR,failReason);
        }
        LanUserResp lanUserResp = cacheConfiguration.userInfo.getUnchecked(token);
        reqDo.setUserId(lanUserResp.getUserId());
        lanBookingActivityRecordMapper.insert(reqDo);
        return BaseResponse.success();
    }

    private String checkAcIsValid(Long activityId){
        LambdaQueryWrapper<LanBookingActivityDO> larQw = new LambdaQueryWrapper<>();
        larQw.eq(LanBookingActivityDO::getId,activityId);
        larQw.eq(LanBookingActivityDO::getIsDeleted,0);
        LanBookingActivityDO activityDO = lanBookingActivityMapper.selectOne(larQw);
        if(Objects.isNull(activityDO)){
            return "活动不存在";
        }
        if(activityDO.getStatus() != 1){
            return "活动已下架";
        }
        Date nowD = new Date();
        if(activityDO.getStartTime().after(nowD) || activityDO.getEndTime().before(nowD)){
            return "当前不在活动时间范围内";
        }
        return null;
    }

}
